package com.snow.auth.service;

import cn.hutool.crypto.digest.DigestUtil;
import com.snow.auth.component.AuthComponent;
import com.snow.auth.entity.*;
import com.snow.auth.repository.*;
import com.snow.exception.CommonRuntimeException;
import com.snow.jpa.BaseService;
import com.snow.model.ILoginUser;
import com.snow.starter.SnowAutoConfiguration;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Slf4j
@Service
public class SystemTenantService extends BaseService<SystemTenantRepository, SystemTenant, Integer> {

    private final SystemUserRepository systemUserRepository;
    private final SystemUserRoleRepository systemUserRoleRepository;
    private final SystemDeptRepository systemDeptRepository;
    private final AuthComponent authComponent;
    private final SnowAutoConfiguration snowAutoConfiguration;
    private final SystemRoleRepository systemRoleRepository;
    private final SystemPostRepository systemPostRepository;
    private final SystemUserPostRepository systemUserPostRepository;

    public SystemTenantService(SystemTenantRepository repository
            , SystemUserRepository systemUserRepository
            , SystemUserRoleRepository systemUserRoleRepository
            , SystemDeptRepository systemDeptRepository
            , AuthComponent authComponent, SnowAutoConfiguration snowAutoConfiguration, SystemRoleRepository systemRoleRepository, SystemPostRepository systemPostRepository, SystemUserPostRepository systemUserPostRepository) {
        super(repository);
        this.systemUserRepository = systemUserRepository;
        this.systemUserRoleRepository = systemUserRoleRepository;
        this.systemDeptRepository = systemDeptRepository;
        this.authComponent = authComponent;
        this.snowAutoConfiguration = snowAutoConfiguration;
        this.systemRoleRepository = systemRoleRepository;
        this.systemPostRepository = systemPostRepository;
        this.systemUserPostRepository = systemUserPostRepository;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public SystemTenant save(SystemTenant systemTenant) {
        systemTenant.setSubdomain(systemTenant.getSubdomain());
        long count = lambdaQuery().equal("subdomain", systemTenant.getSubdomain()).count();
        if (count > 0) {
            throw new CommonRuntimeException("子域名重复，重新设置");
        }
        List<SystemTenant> tenantList = super.findAllBy("phone", systemTenant.getPhone());
        if (!tenantList.isEmpty()) {
            throw new CommonRuntimeException("手机号已存在，请重新设置");
        }

        SystemTenant tenant = super.save(systemTenant);
        // 初始化部门
        SystemDept dept = new SystemDept();
        dept.setParentId(0);
        dept.setDeptName(tenant.getCompanyName());
        dept.setSort(0);
        dept.setStatus(1);
        ILoginUser loginUser = authComponent.getCurrentUser();
        dept.setCreateInfo(loginUser);
        dept.setTenantId(tenant.getId());
        systemDeptRepository.save(dept);
        // 初始化管理员用户
        SystemUser user = new SystemUser();
        user.setAccount(tenant.getPhone());
        user.setDeptId(dept.getId());
        user.setDeptName(dept.getDeptName());
        user.setAccount(tenant.getPhone());
        user.setPassword(DigestUtil.md5Hex(snowAutoConfiguration.getDefaultPwd()).toUpperCase());
        user.setRealName(tenant.getName());
        user.setPhone(tenant.getPhone());
        user.setStatus(1);
        user.setSystemAdmin(false);
        user.setPreviewUser(false);
        user.setDataScope(0);
        user.setCreateInfo(loginUser);
        user.setTenantId(tenant.getId());
        user.setAvatar("https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif");
        systemUserRepository.save(user);
        SystemRole templateRole = systemRoleRepository.findById(1).orElseThrow(() -> new CommonRuntimeException("租户默认管理员角色模板不存在"));
        // 新建租户管理员角色
        SystemRole tenantRole = new SystemRole();
        tenantRole.setTenantId(tenant.getId());
        tenantRole.setName(tenant.getCompanyName() + "系统管理员使用角色(" + tenant.getName() + ")");
        tenantRole.setPermissions(templateRole.getPermissions());
        tenantRole.setCreateInfo(loginUser);
        tenantRole.setRemark("新建租户时，系统自动为该租户【" + tenant.getCompanyName() + "】(联系人：" + tenant.getName() + ")添加系统默认管理员角色");
        systemRoleRepository.save(tenantRole);
        // 关联系统角色
        SystemUserRole userRole = new SystemUserRole();
        userRole.setUserId(user.getId());
        userRole.setRoleId(tenantRole.getId());
        userRole.setTenantId(tenant.getId());
        systemUserRoleRepository.save(userRole);
        // 初始化岗位
        SystemPostEntity post = new SystemPostEntity();
        post.setName("系统管理员");
        post.setCreateInfo(loginUser);
        post.setTenantId(tenant.getId());
        systemPostRepository.save(post);
        SystemUserPostEntity userPost = new SystemUserPostEntity(user.getId(), post.getId());
        systemUserPostRepository.save(userPost);
        return tenant;
    }


    @Override
    public SystemTenant delete(Integer integer) {
        SystemTenant deleteTenant = super.delete(integer);
        if (deleteTenant.getName().contains("测试") && deleteTenant.getCompanyName().contains("测试")) {
            log.info("测试租户，删除所有关联用户和关联部门等信息");
            // 删除租户的所有用户
            systemUserRepository.lambdaQuery()
                    .disTenantFilter()
                    .equal("tenantId", deleteTenant.getId())
                    .delete();
            // 删除租户的所有用户角色
            systemUserRoleRepository.lambdaQuery()
                    .disTenantFilter()
                    .equal("tenantId", deleteTenant.getId())
                    .delete();
            // 删除租户的所有部门
            systemDeptRepository.lambdaQuery()
                    .disTenantFilter()
                    .equal("tenantId", deleteTenant.getId())
                    .delete();
        }
        return deleteTenant;
    }
}
